<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>贪吃蛇</title>
<link rel="stylesheet" type="text/css" href="snake.css">
</head>
<body>
	<div id="container">
		<h3>基于html5的贪吃蛇小游戏</h3>
		<hr/>
		<!--状态信息栏-->
		<div id="status">
			<!--历史最高分-->
			<div class="box">
				历史最高分：<span id="bestScore">0</span>
			</div>
			<!--当前分数-->
			<div class="box">
				当前分数：<span id="currentScore">0</span>
				
			</div>
		</div>
		<!--设置游戏画面-->
		<canvas id="myCanvas" width="400" height="400" style="border:1px solid">
			
		</canvas>
		<!--游戏按钮-->
		<div>
			<button onclick="window.location.reload()">重新开始</button>
		</div>	
	</div>
	<script>
		//=============
		//游戏参数设置
		//=============
		//游戏界面刷新的时间间隔（数字越大，蛇的速度越慢）
		var time=200;
		//蛇的身长
		var t=3;
		//记录蛇的运行轨迹，用数组记录每一个坐标点
		var snakeMap=[];
		//蛇身单元格大小
		var w=10;
		//方向代码：左37，上38，右39，下40；
		var direction=37;
		//蛇身坐标
		var x=0;
		var y=0;
		//食物的起始坐标
		var foodx=0;
		var foody=0;
		//当前得分
		var score=0;
		//历史最高分
		var bestScore=0;
		//画布的宽和高
		var width=400;
		var height=400;
		//根据id找到指定的画布
		var canvas=document.getElementById("myCanvas");
		//创建2d的context对象
		var context=canvas.getContext("2d");

		//获得历史最高分
		showBestScore();

		//开始游戏
		GameStart();

		//==============
		//显示历史最高分纪录
		//==============
		function showBestScore(){
			//从本地存储数据中读取历史最高分
			bestScore=localStorage.getItem("bestScore");
			//如果尚未记录最高分，则重置0
			if(bestScore==null)
				bestScore=0;
			//讲历史最高分跟新到状态栏中
			var best=document.getElementById("bestScore");
			best.innerHTML=bestScore;
		}
		//==========
		//启动游戏
		//==========
		function GameStart(){
			//调用drawFood()函数在水肌位置绘制一个食物
			drawFood();
			//随机生成贪吃蛇的舌头坐标
			x=Math.floor(Math.random()*width/w)*w;
			y=Math.floor(Math.random()*height/w)*w;

			//随机 生成贪吃蛇的前进坐标
			direction=37+Math.floor(Math.random()*4);

			//每隔time毫秒刷新一次游戏内容
			setInterval("gameRefresh()",time);

		}
		//============
		//游戏界面刷新函数
		//============
		function gameRefresh(){
			//将当前坐标数据添加到贪吃蛇的运动轨迹坐标系中
			snakeMap.push({
				'x':x,
				'y':y
			});
			//绘制贪吃蛇
			drawSnake();

			//根据方向移动舌头的下一个位置
			switch(direction){
				//左37
				case 37:
				x-=w;
				break;
				//上38
				case 38:
				y-=w;
				break;
				//右39
				case 39:
				x+=w;
				break;
				//下40
				case 40:
				y+=w;
				break;
			}
			//碰撞检测，返回值0表示没有撞到障碍物
			var code=detectCollision();
			//如果返回值不等于0，表示游戏失败
			if(code!=0){
				//如果过当前分数高于历史最高分，则跟新历史最高分
				if(score>bestScore)
					localStorage.setItem("bestScore",score);
				//返回值1表示撞到墙壁
				if(code==1){
					alert("撞到了墙壁，游戏失败！当前得分："+ score);
				}
				//返回值为2表示撞到了蛇身
				if(code==2){
					alert("撞到了蛇身，游戏失败！当前得分："+score);
				}
				//重新加载页面
			window.location.reload();
			}
		//吃到食物的判定
		if(foodx==x&&foody==y){
			//吃到一次食物家10分
			score+=10;
			//跟新状态栏中的当前分数
			var currentScore=document.getElementById("currentScore");
			currentScore.innerHTML=score;
			//在随机位置绘制下一个食物
			drawFood();
			//蛇身的长度家1 
			t++;
		}
	}
		//===============
		//绘制贪吃蛇函数
		//===============
		function drawSnake(){
			//设置蛇身内部填充颜色
			context.fillStyle="lightblue";
			//绘制最新位置的蛇身矩形
			context.fillRect(x,y,w,w);

			//数组只保留蛇身长度的数据，如果蛇前进了则删除最旧的坐标数据
			if(snakeMap.length>t) {
				//删除数组的第一项，既蛇尾部的最后一个位置的坐标
				var lastBox=snakeMap.shift();
				//清楚蛇的尾部最后一个位置，从而实现移动效果
				context.clearRect(lastBox['x'],lastBox['y'],w,w);
			}
		}
		//============
		//该变蛇方向的按钮监听
		//=============
		document.onkeydown=function(e){
			//根据按键跟新前进方向code:左37，上38，右39，下40
			if(e.keyCode==37||e.keyCode==38||e.keyCode==39||e.keyCode==40)
				direction=e.keyCode;
		}
		//=========
		//碰撞检测函数
		//=========
		function detectCollision(){
			//蛇头碰撞到了四周的墙壁，游戏失败
			if(x>width||y>height||x<0||y<0){
				return 1;
			}
			//蛇头碰到了蛇身，游戏失败
			for(var i=0;i<snakeMap.length;i++){
				if(snakeMap[i].x==x&&snakeMap[i].y==y){
					return 2;
				}
			}
			return 0;
		}
		//===========
		//绘制食物函数
		//===========
		function drawFood(){
			//随机生成食物坐标
			foodx=Math.floor(Math.random()*width/w)*w;
			foody=Math.floor(Math.random()*height/w)*w;
			//内部颜色填充
			context.fillStyle="#ff0000";
			//绘制矩形
			context.fillRect(foodx,foody,w,w);
		}
	</script>

</body>
</html>